home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / misc / emu / arosdev.lha / AROS / rom / utility / udivmod32.c < prev    next >
C/C++ Source or Header  |  1997-02-03  |  4KB  |  146 lines

  1. /*
  2.     Copyright (C) 1995-1997 AROS - The Amiga Replacement OS
  3.     $Id: udivmod32.c,v 1.2 1997/02/03 02:58:32 ldp Exp $
  4.  
  5.     Desc: UDivMod32 - divide two 32 bit numbers.
  6.     Lang: english
  7. */
  8. #include "utility_intern.h"
  9.  
  10. /*****************************************************************************
  11.  
  12.     NAME */
  13. #include <proto/utility.h>
  14.  
  15.         AROS_LH2(ULONG, UDivMod32,
  16.  
  17. /*  SYNOPSIS */
  18.         AROS_LHA(ULONG, dividend, D0),
  19.         AROS_LHA(ULONG, divisor, D1),
  20.  
  21. /*  LOCATION */
  22.         struct Library *, UtilityBase, 26, Utility)
  23.  
  24. /*  FUNCTION
  25.         Perform the 32 bit unsigned division and modulus of dividend by
  26.         divisor, that is dividend / divisor. Will return both the
  27.         quotient and the remainder.
  28.  
  29.     INPUTS
  30.         dividend        -   The number to divide into (numerator).
  31.         divisor         -   The number to divide by (denominator).
  32.  
  33.     RESULT
  34.         For m68k assembly programmers,
  35.             D0: quotient
  36.             D1: remainder
  37.  
  38.         For HLL programmers,
  39.             the quotient
  40.  
  41.     NOTES
  42.         The utility.library math functions are unlike all other utility
  43.         functions in that they don't require the library base to be
  44.         loaded in register A6, and they also save the values of the
  45.         address registers A0/A1.
  46.  
  47.         This function is mainly to support assembly programers, and is
  48.         probably of limited use to higher-level language programmers.
  49.  
  50.     EXAMPLE
  51.  
  52.     BUGS
  53.         It is impossible for C programmers to obtain the value of
  54.         remainder.
  55.  
  56.     SEE ALSO
  57.         SDivMod32(), SMult32(), SMult64(), UMult32(), UMult64()
  58.  
  59.     INTERNALS
  60.         May actually be handled by code that is in config/$(KERNEL)
  61.         This is the case for m68k-native.
  62.  
  63.     HISTORY
  64.         29-10-95    digulla automatically created from
  65.                             utility_lib.fd and clib/utility_protos.h
  66.  
  67. *****************************************************************************/
  68. {
  69.     AROS_LIBFUNC_INIT
  70.  
  71.     return dividend / divisor;
  72.  
  73. #if 0
  74. #error The UDivMod32() emulation code does NOT work!
  75.  
  76.     /* This does _NOT_ work, so do not use it */
  77.  
  78.     UWORD a,b,c,d;
  79.     UQUAD result;
  80.     LONG quo, rem;
  81.  
  82.     a = dividend >> 16;
  83.     b = dividend & 0xFFFF;
  84.     c = divisor >> 16;
  85.     d = divisor & 0xFFFF;
  86.  
  87.     /* See if the numerator is 32 bits or 16... */
  88.     if(a == 0)
  89.     {
  90.         /* 16 bits */
  91.         if(c != 0)
  92.         {
  93.             /* 16/32 -> quo = 0; rem = dividend */
  94.             quo = 0;
  95.             rem = dividend;
  96.         }
  97.         else
  98.         {
  99.             /* 16/16 -> can be done in native div */
  100.             quo = b / d;
  101.             rem = b % d;
  102.         }
  103.     }
  104.     else
  105.     {
  106.         /* 32 bit numerator */
  107.         if(c != 0)
  108.         {
  109.             /* 32 bit denominator, quo ~= a/c */
  110.             quo = a/c;
  111.         }
  112.         else
  113.         {
  114.             /* 16 bit denominator, quo ~= (a/d) * 65536 */
  115.             quo = (a / d) << 16;
  116.         }
  117.         /* Get the error */
  118.         rem = dividend - UMult32(quo,divisor);
  119.  
  120.         /* Take the remainder down to zero */
  121.         while(rem > 0)
  122.         {
  123.             quo++;
  124.             rem -= divisor;
  125.         }
  126.  
  127.         /* However a -ve remainder is silly,
  128.            this also catches the case when the remainder is < 0 from the
  129.            guess
  130.         */
  131.         while(rem < 0)
  132.         {
  133.             quo--;
  134.             rem += divisor;
  135.         }
  136.     }
  137.     SET_HIGH32OF64(result, quo);
  138.     SET_LOW32OF64(result, rem);
  139.  
  140.     return result;
  141.  
  142. #endif
  143.     AROS_LIBFUNC_EXIT
  144.  
  145. } /* UDivMod32 */
  146.